from datetime import datetime

from app2 import db


class Collection(db.Model):
    """新闻收藏"""
    __tablename__ = "user_collection"
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True)  # 新闻编号
    news_id = db.Column(db.Integer, db.ForeignKey("news.id"), primary_key=True)  # 分类编号
    create_time = db.Column(db.DateTime, default=datetime.now)  # 收藏创建时间


class News(db.Model):
    """新闻"""
    __tablename__ = "news"

    id = db.Column(db.Integer, primary_key=True)  # 新闻编号
    title = db.Column(db.String(256), nullable=False)  # 新闻标题
    # source = db.Column(db.String(64), nullable=False)  # 新闻来源
    digest = db.Column(db.String(512), nullable=False)  # 新闻摘要
    content = db.Column(db.Text, nullable=False)  # 新闻内容
    clicks = db.Column(db.Integer, default=0)  # 浏览量
    index_image_url = db.Column(db.String(256))  # 新闻列表图片路径
    baidu_address_url = db.Column(db.String(256))  # 百度网盘下载地址
    github_address_url = db.Column(db.String(256))  # github地址

    other_address_url = db.Column(db.String(256))  # 其他地址

    category_id = db.Column(db.Integer, db.ForeignKey("category.id"))
    # user_id = db.Column(db.Integer, db.ForeignKey("user.id"))  # 当前新闻的作者id
    # status = db.Column(db.Integer, default=0)  # 当前新闻状态 如果为0代表审核通过，1代表审核中，-1代表审核不通过
    # reason = db.Column(db.String(256))  # 未通过原因，status = -1 的时候使用
    create_time = db.Column(db.DateTime, default=datetime.now)  # 记录的创建时间
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)  # 记录的更新时间
    category = db.relationship('Category', backref='news')
    # 当前新闻的喜欢用户
    user = db.relationship('User', secondary=Collection.__tablename__, backref=db.backref('news', lazy='dynamic'), lazy="dynamic")
    # 当前新闻的所有评论
    comments = db.relationship("Comment", lazy="dynamic")
    # # 当前新闻的喜欢用户
    collection = db.relationship('Collection', backref='news')

    def to_dict(self):
        news_dict = {
            "id": self.id,
            "title": self.title,
            # "source": self.source,
            "digest": self.digest,
            # "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "create_time": self.create_time.strftime("%Y-%m-%d"),
            "index_image_url": self.index_image_url,
            "clicks": self.clicks,
            "comments": self.comments.count(),
            "user_count": self.user.count(),
            "category_name": self.category.name
        }
        return news_dict

    def to_collect_dict(self):
        news_dict = {
            "id": self.id,
            "title": self.title,
            "create_time": self.create_time.strftime("%Y-%m-%d")
        }

        return news_dict

    # def to_news_list_dict(self):
    #     resp_dict = {
    #         "id": self.id,
    #         "title": self.title,
    #         "status": self.status,
    #         "reason": self.reason,  # 未通过原因
    #         "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
    #     }

        # return resp_dict


class Category(db.Model):
    """新闻分类"""
    __tablename__ = "category"

    id = db.Column(db.Integer, primary_key=True)  # 分类编号
    name = db.Column(db.String(64), nullable=False)  # 分类名
    create_time = db.Column(db.DateTime, default=datetime.now)  # 记录的创建时间
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)  # 记录的更新时间


class Follow(db.Model):
    """用户关注表"""
    __tablename__ = "follow"
    followed_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)  # 被关注人的id
    follower_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)  # 被粉丝id


class User(db.Model):
    """用户"""
    __tablename__ = "user"

    id = db.Column(db.Integer, primary_key=True)  # 用户编号
    vip = db.Column(db.Integer, default=0)  # vip等级
    vip_create_time = db.Column(db.DateTime)  # vip充值时间
    sign_in = db.Column(db.String(32))  # 每天签到时间
    # a = db.Column(db.DateTime)  # 辅助字段
    integral = db.Column(db.Integer, default=0)  # 积分
    nick_name = db.Column(db.String(32), unique=True, nullable=False)  # 用户昵称
    password_hash = db.Column(db.String(128), nullable=False)  # 加密的密码
    mobile = db.Column(db.String(11), unique=True, nullable=False)  # 手机号
    avatar_url = db.Column(db.String(256))  # 用户头像路径
    create_time = db.Column(db.DateTime, default=datetime.now)  # 注册时间
    last_login = db.Column(db.DateTime, default=datetime.now)  # 最后一次登录时间
    is_admin = db.Column(db.Boolean, default=False)
    signature = db.Column(db.String(512))  # 用户签名

    # 用户针对新闻的评论信息
    comments = db.relationship("Comment", backref="user")
    # 用户点过赞的评论信息
    like_comments = db.relationship("Comment", secondary="comment_like", lazy='dynamic')

    gender = db.Column(  # 性别
        db.Enum(
            "MAN",  # 男
            "WOMAN"  # 女
        ),
        default="MAN"
    )
    followers = db.relationship('User',
                                secondary=Follow.__tablename__,
                                primaryjoin=(id == Follow.followed_id),
                                secondaryjoin=(id == Follow.follower_id),
                                # backref='followed',
                                backref=db.backref('followed', lazy='dynamic'),  #  # 修改反向引用的加载方法
                                # lazy="select")  # 正向引用默认
                                lazy='dynamic')  # 修改正向引用的加载方法

    collection_news = db.relationship("News",
                                      secondary=Collection.__table__,
                                      backref=db.backref('collection_user', lazy='dynamic'),
                                      lazy='dynamic')

    # 正反向引用的加载方法默认lazy为select, 即
    # select - (默认)
    # 后台会用select语句一次性加载所有数据，即访问到属性的时候，就会全部加载该属性的数据。
    # 若数据量巨大，或侵占大量内存

    # dynamic - 在访问属性的时候，并不在内存中加载数据，而是返回一个query对象,
    # 需要执行相应方法才可以获取对象。适用于数据量大的时候。
    # 只返回一个query查询对象，需要时手动加条件查询query.all()或query.filter(), query.count()等
    # head_img = db.Column(db.String(200), default="/static/upload/images/timg.jpg")
    def to_follow_info(self):
        ret = {
            "id": self.id,
            "avatar_url": self.avatar_url,
            "nick_name": self.nick_name,
            "signature": self.signature,
            "news_num": self.news.count(),
            "followers": self.followers.count()
        }
        return ret

    def to_user_list_dict(self):
        ret = {
            "name": self.nick_name,
            "mobile": self.mobile,
            "gender": self.gender,
            "signature": self.signature,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "last_login_time": self.last_login.strftime("%Y-%m-%d %H:%M:%S"),
            "is_admin": self.is_admin,
        }
        return ret


class Comment(db.Model):
    """评论"""
    __tablename__ = "comment"
    id = db.Column(db.Integer, primary_key=True)  # 评论编号
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)  # 用户id
    news_id = db.Column(db.Integer, db.ForeignKey("news.id"), nullable=False)  # 新闻id
    content = db.Column(db.Text, nullable=False)  # 评论内容
    create_time = db.Column(db.DateTime, default=datetime.now)  # 记录的创建时间
    update_time = db.Column(db.DateTime, default=datetime.now)  # 记录的更新时间
    parent_id = db.Column(db.Integer, db.ForeignKey("comment.id"))  # 父评论id
    parent = db.relationship("Comment", remote_side=id)  # 自关联
    like_count = db.Column(db.Integer, default=0)  # 点赞条数

    def to_basic_dict(self):
        ret = {
            "id": self.id,
            "user_id": self.user_id,
            "user_avatar_url": self.user.avatar_url,
            "user_nick_name": self.user.nick_name,
            "content": self.content,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "parent": self.parent.to_basic_dict() if self.parent else None,
            "like_count": self.like_count,
            "user_vip": self.user.vip
        }
        return ret


class CommentLike(db.Model):
    """评论点赞"""
    __tablename__ = "comment_like"
    comment_id = db.Column("comment_id", db.Integer, db.ForeignKey("comment.id"), primary_key=True)  # 评论编号
    user_id = db.Column("user_id", db.Integer, db.ForeignKey("user.id"), primary_key=True)  # 用户编号


class Goods(db.Model):
    """商品"""
    __tablename__ = "goods"

    id = db.Column(db.Integer, primary_key=True)  # 商品编号
    title = db.Column(db.String(256), nullable=False)  # 商品标题
    content = db.Column(db.Text, nullable=False)  # 商品内容
    index_image_url = db.Column(db.String(256))  # 商品列表图片路径
    money = db.Column(db.Integer)  # 商品原价钱
    integral = db.Column(db.Integer)  # 兑换商品所需积分
    on_off = db.Column(db.Integer)  # 商品剩余份数
    create_time = db.Column(db.DateTime, default=datetime.now)  # 记录的创建时间
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)  # 记录的更新时间
    good_buy_address = db.Column(db.String(256))  # 商品直接购买原地址


class Order(db.Model):
    """商品订单"""
    __tablename__ = "order"
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"))  # 用户编号
    good_id = db.Column(db.Integer, db.ForeignKey("goods.id"))  # 商品编号
    create_time = db.Column(db.DateTime, default=datetime.now)  # 创建订单时间

    # 该订单的用户
    user = db.relationship("User", backref="order")
    # 该订单的商品
    good = db.relationship("Goods", backref="order")

    def user_order_good(self):
        ret = {
            "user_id": self.user.id,
            "user_nick_name": self.user.nick_name,
            "user_mobile": self.user.mobile,
            "good_id": self.good.id,
            "good_title": self.good.title,
            "create_time": self.create_time
        }
        return ret


class Card(db.Model):
    """发布的卡密表"""
    __tablename__ = "card"
    id = db.Column(db.Integer, primary_key=True)
    num = db.Column(db.Integer)  # 卡号
    password = db.Column(db.Integer)  # 卡密

